#ifndef OVERSEER_H
#define OVERSEER_H

#include <Ogre.h>
#include <boost/thread.hpp>

class State;
class InputManager;
class GUIManager;

class Overseer : public Ogre::Singleton<Overseer>, public Ogre::WindowEventListener
{
    enum StateOperation {STATE_NONE,STATE_CHANGE,STATE_PUSH,STATE_POP};
public:
    Overseer();
    bool initialise();
    void setupResources();

    bool isRunning();
    void update();

    void changeState(State *s);
    void pushState(State *s);
    void popState();
    State* getCurrentState();

    void lockRendering(){stateMutex.lock();}
    void unlockRendering(){stateMutex.unlock();}

    InputManager* getInputManager();
    GUIManager* getGUIManager();

    void exit();
    void cleanup();
protected:
    void windowResized(Ogre::RenderWindow *rw);
    void windowClosed(Ogre::RenderWindow *rw);
    void windowFocusChange(Ogre::RenderWindow *rw);
private:
    void manageStates();
    InputManager *inputManager;
    GUIManager *guiManager;

    std::vector<State*> states;
    boost::mutex stateMutex, stateOpMutex;

    Ogre::Root *root;
    Ogre::RenderWindow *window;

    Ogre::Timer timer;
    Ogre::Real lastTime;
    State *nextState;
    StateOperation stateOp;
    bool running;
};

#endif
